<?php
/**
 * Created by PhpStorm.
 * User: 小蛮哼哼哼
 * Email: 243194993@qq.com
 * Date: 2021/11/17
 * Time: 16:57
 * motto: 现在的努力是为了小时候吹过的牛逼！
 */

declare(strict_types=1);

namespace app\common\business;

use app\common\lib\Show;
use app\common\lib\Status;
use app\common\model\mysql\GrabSheet;
use app\common\model\mysql\Order as ModelObj;
use app\common\model\mysql\OrderDetail;
use app\common\validate\Order as ValObj;
use EasyWeChat\Factory;
use think\Exception;
use think\facade\Log;
use think\helper\Str;

class PlaceOrder extends Base
{
    protected $valObj = null;
    protected $modelObj = null;

    public function __construct()
    {
        $this->valObj = new ValObj();
        $this->modelObj = new ModelObj();
    }

    public function getOrderByOrderId(string $order_id = '')
    {
        try {
            $order = $this->modelObj->getOrderByOrderId($order_id);
        } catch (\Exception $e) {
            throw new Exception("订单错误");
        }
        return $order;
    }

    /**
     * @param int $time
     * @return bool
     * @throws Exception
     */
    public function abandoned(int $time = 0)
    {
        try {
            $order = $this->modelObj->where('create_time', '<', $time)
                ->where('payStatus', 0)
                ->select()
                ->toArray();
        } catch (\Exception $e) {
            throw new Exception("查询失败");
        }
        $this->modelObj->startTrans();
        try {
            $this->modelObj->where('id', 'in', array_column($order, 'id'))
                ->delete();
            (new OrderDetail())->where('order_id', 'in', array_column($order, 'id'))
                ->delete();
            $this->modelObj->commit();
        } catch (\Exception $e) {
            $this->modelObj->rollback();
            throw new Exception("删除失败");
        }
        return true;
    }

    /**
     * @param int $time
     * @return ModelObj|bool
     * @throws Exception
     */
    public function invalid(int $time = 0)
    {
        try {
            $invalid = $this->modelObj->getOrderInvalid($time);
        } catch (\Exception $e) {
            throw new Exception("查询失败");
        }
        if (empty($invalid)) {
            return true;
        }
        $ids = array_column($invalid, 'o_id');
        try {
            $res = $this->modelObj->updateByIdsInvalid($ids);
        } catch (\Exception $e) {
            throw new Exception("操作失败");
        }
        return $res;
    }

    /**
     * @param int $theatreId
     * @param array $oldArray
     * @param string $openid
     * @return mixed
     * @throws Exception
     */
    public function setOrderByData(int $theatreId = 0, array $oldArray = [], string $openid = "")
    {
        //获取座位
        try {
            $theatre = (new \app\common\model\mysql\Theatre())->getBaseById((int)$theatreId);
        } catch (\Exception $e) {
            throw new Exception("查询失败");
        }
        if (!$theatre) {
            throw new Exception("剧场不存在");
        }
        $theatre = $theatre->toArray();
        //选座
        $number = count($oldArray);
        //查询限制 和已经购买了张数
        if ($theatre['person'] != 0) {
            if ($number > $theatre['person']) {
                throw new Exception("只能购买{$theatre['person']}张");
            }
            try {
                $count = $this->modelObj->getOrderByOpenidCount($openid, $theatreId);
            } catch (\Exception $e) {
                throw new Exception('内部异常');
            }
            if ($count) {
                $count = $count['count'];
                if ($count >= $number) {
                    throw new Exception("只能购买{$theatre['person']}张");
                }
            }

        }
        //获取座位对应的价格
        $seatDetail = (new \app\common\model\mysql\SeatDetail())->getBaseByIdsValue($oldArray);
        if (empty($seatDetail)) {
            throw new Exception("座位错误");
        }
        $money = 0;
        foreach ($seatDetail as $value) {
            $money += $value['money'];
        }
//        $money = $theatre['money'] * $number;
        //根据openid查询
        $insert_data = [
            "money" => $money,
            "theatre_id" => $theatre['id'],
            "order_id" => date('YmdHis') . Str::random(6, 1),
            "openid" => $openid,
            "seat" => Show::json_encode($oldArray),
            "number" => $number,
            "theatreCate" => $theatre['theatre_cate_id'],
            "venue" => $theatre['venue'],
            "theatre_time" => strtotime($theatre['start_time']),
            "create_time" => time(),
            "update_time" => time()
        ];
        //查询座位是否选定
        $this->modelObj->startTrans();
        try {
            $order_id = $this->modelObj->insertGetId($insert_data);
            $seat = [];
            foreach ($oldArray as $k => $v) {
                $seat[$k] = [
                    "theatre_id" => $theatre['id'],
                    "seat_id" => $v,
                    "status" => Status::mysql_normal,
                    "order_id" => $order_id,
                    "create_time" => time(),
                    "update_time" => time(),
                    "code" => Str::random(6, 1)
                ];
            }
            (new OrderDetail())->insertAll($seat);
            $this->modelObj->commit();
        } catch (\Exception $e) {
            $this->modelObj->rollback();
            Log::error("bus-placeOrder-setOrder:" . $e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
            throw new Exception("创建失败");
        }
        return $insert_data['order_id'];
    }

    public function getOrderByIdMoney(string $order_id = '', string $openid = '')
    {
        try {
            $order = $this->modelObj->getOrderByOrderId($order_id);
        } catch (\Exception $e) {
            throw new Exception("订单查询失败");
        }
        if (!$order) {
            throw new Exception("订单不存在");
        }
        $order = $order->toArray();
        if ($order['openid'] != $openid) {
            throw new Exception("用户错误");
        }
        //查询演出信息
        try {
            $theatre = (new \app\common\model\mysql\Theatre())->getBaseById((int)$order['theatre_id'], '*,thumb as root_path_thumb,venue as get_venue,theatre_cate_id as get_theatre_cate_id,start_time as start_day,start_time as start_day_time,end_time as end_day_time,start_time as start_date_a');
        } catch (\Exception $e) {
            throw new Exception("演出错误");
        }
        if (!$theatre) {
            throw new Exception("演出错误");
        }
        $theatre['order_id'] = $order['order_id'];
        $theatre['mobile'] = $order['mobile'];
        $theatre['money'] = $order['money'];
        //获取座位
        try {
            $seatDetail = (new \app\common\model\mysql\SeatDetail())
                ->where("SeatCode", 'in', Show::json_decode($order['seat']))
                ->select()->toArray();
        } catch (\Exception $e) {
            throw new Exception("座位获取失败");
        }
        if (empty($seatDetail)) {
            throw new Exception("还没选择座位");
        }
        $seat = "";
        foreach ($seatDetail as $v) {
            $seat .= $v['RowNum'] . "排" . $v['ColumnNum'] . "座 ";
        }
        $theatre['seat'] = $seat;
        $theatre = $theatre->toArray();
        $theatre['create_time'] = $order['create_time'];
        return $theatre ;
    }

    /**
     * @param string $order_id
     * @param string $mobile
     * @return mixed|void
     * @throws Exception
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function confirmPayment(string $order_id = '', string $mobile = '')
    {
        try {
            $order = $this->modelObj->getOrderByOrderId($order_id);
        } catch (\Exception $e) {
            throw new Exception("订单错误");
        }
        if (!$order) {
            throw new Exception("订单不存在");
        }
        //修改手机号
        try {
            $res = $order->save([
                "mobile" => $mobile
            ]);
        } catch (\Exception $e) {
            throw new Exception("修改手机失败");
        }
        if (!$res) {
            throw new Exception("手机修改失败");
        }
        $order = $order->toArray();
        if ($order['payStatus'] != 0) {
            throw new Exception("订单已经支付");
        }
        $notify = (string)url('/api/notify/jsapi', [], true, true);
        $app = Factory::payment(config('wechat.miniPay'));
        $payData = [
            'body' => '跑腿帮忙',
            'out_trade_no' => $order['order_id'],
            'total_fee' => $order['money'] * 100,
            'spbill_create_ip' => request()->ip(), // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
            'notify_url' => $notify, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $order['openid'],
        ];
        $result = $app->order->unify($payData);
        if ($result['return_code'] == "SUCCESS") {
            if ($result['result_code'] == "SUCCESS") {
                $res = $app->jssdk->bridgeConfig($result['prepay_id']);
                if ($res) {
                    return Show::json_decode($res);
                }
            } else {
                Log::error(Show::json_encode($result));
                throw new Exception("业务返回失败");
            }
        } else {
            throw new Exception($result['return_msg']);
        }
    }

    /**
     * @param string $openid
     * @param int $type
     * @return array
     * @throws Exception
     */
    public function getOrderListInfo(string $openid = '', int $type = 0)
    {
        try {
            if ($type == 1 || $type == 2 || $type == 3) {
                $order = $this->modelObj->getOrderListInfo($openid, $type, '*,theatre_id as get_theatre_id_data,theatre_time as get_theatre_time');
            } else if ($type == 4) {
                $order = $this->modelObj->getOrderListInfoNotPay($openid, $type, '*,theatre_id as get_theatre_id_data,theatre_time as get_theatre_time');
            }
        } catch (\Exception $e) {
            throw new Exception("订单错误");
        }
        return $order;
    }

    /**
     * @param string $order_id
     * @return array
     * @throws Exception
     */
    public function getOrderDetailByOrderId(string $order_id = '')
    {
        try {
            $res = $this->modelObj->getOrderByOrderId($order_id, '*,theatre_id as get_theatre_id_data,theatre_time as get_theatre_time ');
        } catch (\Exception $e) {
            throw new Exception("订单查询失败");
        }
        if (!$res) {
            throw new Exception("订单不存在");
        }
        $order = $res->toArray();
        //查询座位详情
        try {
            $seatDetail = (new OrderDetail())->getOrderDetailSeatById($order['theatre_id'], Show::json_decode($order['seat']));
        } catch (\Exception $e) {
            throw new Exception("查询失败");
        }
        if (!empty($seatDetail)) {
            $lists = [];
            try {
                foreach ($seatDetail as $key => $value) {
                    $lists[$key] = $value;
                    $seatDetail = (new \app\common\model\mysql\SeatDetail())->where('SeatCode',$value['seat_id'])->find();
                    $lists[$key]['msg'] = $seatDetail['RowNum'] . "排" . $seatDetail['ColumnNum'] . "座";
                }
            } catch (\Exception $e) {
                Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                throw new Exception("内部发生错误");
            }
            $seatDetail = $lists;
        }
        $order['seatDetail'] = $seatDetail;
        //根据id查询观影码
        return $order;
    }

    /**
     * @param string $order_id
     * @return bool
     * @throws Exception
     */
    public function delOrder(string $order_id = '')
    {
        try {
            $order = $this->modelObj->getOrderByOrderId($order_id);
        } catch (\Exception $e) {
            throw new Exception("查询错误");
        }
        if (!$order) {
            throw new Exception("订单不存在");
        }
        $order = $order->toArray();
        if ($order['state'] == 1) {
            throw new Exception("订单不能删除");
        }
        try {
            $result = $this->modelObj->updateByData($order['id'], [
                'status' => Status::mysql_delete,
                "update_time" => time()
            ]);
        } catch (\Exception $e) {
            throw new Exception("删除失败");
        }
        return $result;
    }

    /**
     * @param array $where
     * @return int|mixed
     * @throws Exception
     */
    public function getOrderByCount(array $where = [])
    {
        try {
            $order = $this->modelObj->field("id,count(*) as count")
                ->where($where)
                ->find();
        } catch (\Exception $e) {
            throw new Exception("查询错误");
        }
        if (!$order) {
            return 0;
        }
        return $order['count'];
    }

    public function write(int $id = 0)
    {
        try {
            $order = $this->modelObj->getBaseById($id);
        } catch (\Exception $e) {
            throw new Exception("查询错误");
        }
        if (!$order) {
            throw new Exception("订单不存在");
        }
        $this->modelObj->startTrans();
        try {
            $this->modelObj->updateByData($order['id'], [
                "state" => 2,
                "update_time" => time(),
                "write_type" => 1,
                "write_time" => time()
            ]);
            $this->modelObj->commit();
        } catch (\Exception $e) {
            $this->modelObj->rollback();
            throw new Exception("订单处理错误");
        }
        return true;
    }
}
